/**
 * ECMAScript 3 基础：
 * 1. ES3 是 JavaScript 的第一个被广泛采用的标准版本，并于 1999 年发布。
 * 2. 在 ES3 中，引入了许多 JavaScript 的基本特性和语法。
 * 3. 以下是 ES3 的一些基础知识：
 * (1).变量和数据类型：
 *     使用 var 关键字声明变量，并支持基本的数据类型，如字符串、数字、布尔值等。
 * (2).运算符和表达式：
 *     支持常见的算术运算符（加减乘除）、比较运算符（大于、小于等）、逻辑运算符（与、或、非）等。
 * (3).条件语句和循环结构：
 *     支持 if-else 条件语句、switch-case 多分支语句以及 for、while、do-while 等循环结构。
 * (4).函数和作用域：
 *     使用 function 关键字定义函数，并支持函数作用域和全局作用域。
 * (5).对象和属性：
 *     使用对象字面量 {} 创建对象，可以通过 . 或 [] 访问对象的属性和方法。
 * (6).数组和字符串：
 *     使用数组字面量 [] 创建数组，并支持常见的数组操作方法，如 push、pop、join 等。
 *     字符串是不可变的，可以使用索引访问字符串的字符。
 * (7).异常处理：
 *     支持 try-catch-finally 异常处理机制，用于捕获和处理运行时错误。
 * (8).正则表达式：
 *     支持正则表达式，用于模式匹配和字符串操作。
 * ECMAScript 5 基础：
 * 1. ES5 是 JavaScript 的第五个版本，它在 2009 年发布，并引入了许多 JavaScript 的重要特性和改进。
 * 2. 以下是 ES5 的一些基础知识：
 * (1).严格模式（Strict Mode）：
 *     ES5 引入了严格模式，通过在代码开头添加 'use strict'; 来启用。严格模式使得 JavaScript 运行在更严格的条件下，减少了一些怪异行为，并且增强了安全性。
 * (2).数组方法：
 *     ES5 引入了一些新的数组方法，例如 forEach、map、filter、reduce 等，使得对数组的操作更加方便和高效。
 * (3).对象属性的描述符：
 *     ES5 引入了 Object.defineProperty 方法，可以精确的定义对象属性的特性，如可枚举性、可写性、可配置性等。
 * (4).JSON 对象：
 *     ES5 引入了原生支持 JSON（JavaScript Object Notation）格式数据的解析和序列化方法 JSON.parse 和 JSON.stringify。
 * (5).Function.prototype.bind 方法：
 *     可以使用 bind 方法来绑定函数的 this 值，使得函数在调用时始终保持指定的上下文。
 * (6).Array.isArray 方法：
 *     ES5 引入了 Array.isArray 方法，用于确定一个值是否为数组类型。
 * (7).Date.now 方法：
 *     ES5 引入了 Date.now 方法，用于快速获取当前时间的时间戳。
 * ECMAScript 6 基础：
 * 1. ES6（ECMAScript 6）是 JavaScript 的一种标准，也被称为 ECMAScript 2015。它引入了许多新的语言特性和语法，使得 JavaScript 更加强大和灵活。
 * 2. 以下是一些 ES6 的基础知识：
 * (1).let 和 const 声明：
 *     let 和 const 关键字用来声明变量和常量，取代了 var 关键字。
 *     let 声明的变量具有块级作用域，而 var 声明的变量则具有函数作用域。
 * (2).箭头函数：
 *     箭头函数是一种更简洁的函数声明方式，使用 => 符号来定义函数。
 * (3).模板字符串：
 *     使用反引号（``）来创建多行字符串和嵌入变量。
 * (4).默认参数：
 *     在函数声明中可以为参数设置默认值。
 * (5).解构赋值：
 *     可以轻松地从数组或对象中提取数据并赋值给变量。
 * (6).展开运算符：
 *     使用 ... 来展开数组或对象，方便地将它们合并到另一个数组或对象中。
 * (7).类和继承：
 *     引入了基于类的面向对象编程模式，包括类的定义、继承和构造函数等概念。
 * (8).模块化：
 *     引入了 import 和 export 关键字，使得 JavaScript 支持原生的模块化开发。
 * (9).Promise：
 *     引入了 Promise 对象，简化了异步操作的处理方式。
 */

'use strict' // 开启严格模式。ES5引入了严格模式，通过在代码开头添加use strict来启用。

const path = require('path')

const defaultSettings = require('./src/settings.js')

function resolve(dir) {
  return path.join(__dirname, dir)
}

// 网页标题
const name = defaultSettings.title || 'vue Admin Template'

// 如果端口设置为80，请使用管理员权限执行命令行。
// 例如<Mac>：sudo-npm-run。
// 也可以通过以下方法更改端口：port=9528 npm run dev 或者 npm run dev--port = 9528
const port = process.env.port || process.env.npm_config_port || 9528

/**
 * 如果你计划在子路径下部署站点，例如：GitHub Pages，则需要设置：publicPath。
 * 如果你计划将站点部署到：https://foo.github.io/bar/，则需要将publicPath应设置为'/bar/'，在大多数情况下，请使用'/'。
 * 详细信息：https://cli.vuejs.org/config/#publicpath
 * 所有配置项说明均可在中找到在：https://cli.vuejs.org/config/
 */
module.exports = {
  publicPath: '/',
  outputDir: 'dist',
  assetsDir: 'static',
  lintOnSave: process.env.NODE_ENV === 'development',
  productionSourceMap: false,
  devServer: {
    port: port,
    open: true,
    overlay: {
      warnings: false,
      errors: true
    },
    // 改动点开启MockJS模拟数据：
    // TODO -> webpack-devser@3.X Use of
    // before: require('./mock/mock-server.js'),
    // TODO -> webpack-devser@4.X Use of
    // onBeforeSetupMiddleware: (app, server, compiler) => { require('./mock/mock-server.js') },
    // 配置代理跨域（注意：但凡修改配置文件之后，都必须重启服务来生效。）
    proxy: {
      '/dev-api': {
        target: 'http://gmall-h5-api.atguigu.cn',
        pathRewrite: {
          '^/dev-api': ''
        }
      }
    }
  },
  // 在webpack的name字段中提供应用程序的标题，这样就可以在index.html中访问它来注入正确的标题。
  configureWebpack: {
    name: name,
    resolve: {
      alias: {
        '@': resolve('src')
      }
    }
  },
  chainWebpack(config) {
    // 它可以提高第一个屏幕的速度，建议打开预加载。
    config.plugin('preload').tap(() => [
      {
        rel: 'preload',
        fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
        include: 'initial'
      }
    ])
    // 当有很多页面时，会导致太多无意义的请求。
    config.plugins.delete('prefetch')
    // 设置svg精灵加载程序。
    config.module.rule('svg').exclude.add(resolve('src/icons')).end()
    config.module.rule('icons').test(/\.svg$/).include.add(resolve('src/icons')).end().use('svg-sprite-loader').loader('svg-sprite-loader').options({ symbolId: 'icon-[name]' }).end()
    config.when(process.env.NODE_ENV !== 'development',
      config => {
        config.plugin('ScriptExtHtmlWebpackPlugin').after('html').use('script-ext-html-webpack-plugin', [{ inline: /runtime\..*\.js$/ }]).end()
        config.optimization.splitChunks({ chunks: 'all', cacheGroups: {
          libs: { name: 'chunk-libs', test: /[\\/]node_modules[\\/]/, priority: 10, chunks: 'initial' },
          elementUI: { name: 'chunk-elementUI', priority: 20, test: /[\\/]node_modules[\\/]_?element-ui(.*)/ },
          commons: { name: 'chunk-commons', test: resolve('src/components'), minChunks: 3, priority: 5, reuseExistingChunk: true }
        }})
        config.optimization.runtimeChunk('single')
      }
    )
  }
}
